import { componentId } from '@/utils/unique'
import action from '@ve/common/interaction/action'
import isArray from 'lodash/isArray'

//extend Data(数据合并)
//迭代器
function forEachOwn(data = [], callback) {
  data.forEach((item, index) => {
    callback && callback.call(this, item, index)
  })
}

//深拷贝对象
function deepClone(obj) {
  if (Array.isArray(obj)) {
    return Array.from(obj)
  } else if (toString.call(obj) === '[object Object]') {
    return Object.assign({}, obj)
  }
  return obj
}

//合并JSON数据
function ExtendJson(_target, _source, isExtend) {
  //数组合并
  if (Array.isArray(_source)) {
    if (isExtend) {
      _target = deepClone(_source)
    } else {
      _target = _target.length ? _target : deepClone(_source)
    }
    return _target
  }
  const tKeys = Object.keys(_target)
  //对象合并
  for (let key in _source) {
    if (typeof _source[key] === 'object' && !['value', 'isExtend'].includes(key)) {
      _target[key] = ExtendJson(_target[key] || (Array.isArray(_source[key]) ? [] : {}), _source[key], _source.isExtend)
    } else if (tKeys.indexOf(key) === -1 || _source.isExtend) {
      if (_source.isExtend && ['value', 'isExtend'].includes(key)) {
        continue
      }
      _target[key] = _source[key]
    }
  }
  deleteAttr(_target, _source)
  return _target
}

//删除不存在的属性
function deleteAttr(_target, _source) {
  const tKeys = Object.keys(_target)
  const sKeys = Object.keys(_source || {})
  forEachOwn(tKeys, (key) => {
    if (['data', 'formData', 'requestData'].includes(key)) {
      return
    }
    if (sKeys.indexOf(key) === -1 && key != '_id') {
      delete _target[key]
    }
  })
}

//执行合并
function extend(target = {}, source = []) {
  //源对象没有值直接返回
  if (!source.length) return target
  //源对象有值
  /*配置说明
    type: 匹配的字段
    ruleOut: 不处理的字段
  */
  const ctrl = [{ type: 'type', ruleOut: ['_id'] }]
  //获取目标对象
  const findSource =
    source.find((item) => {
      return item[ctrl[0].type] === target[ctrl[0].type]
    }) || {}
  const tkeys = Object.keys(target)
  const sKeys = Object.keys(findSource)
  forEachOwn(sKeys, (key) => {
    tkeys.indexOf(key) === -1 && (target[key] = findSource[key])
  })
  //处理规则 先实现后续再优化
  if (target.type && String(target.type).indexOf('uiSelectLayerNew') > -1 && target.type.length > 'uiSelectLayerNew'.length) {
    const targetArr = target.extension.tableColumns.value
    let sourceArr = source.filter((item) => {
      return item.type === target.type
    })
    if (sourceArr.length) {
      sourceArr = sourceArr[0].extension.tableColumns.value
    }
    for (let i = 0; i < targetArr.length; i++) {
      if (targetArr[i]._type !== 'field') {
        continue
      }
      const find = sourceArr.find((item) => {
        return item.field === targetArr[i].field
      })
      if (targetArr[i].openSearch === undefined) {
        if (find && find.openSearch) {
          targetArr[i].openSearch = find.openSearch
          targetArr[i].searchConfig = find.searchConfig
        } else {
          targetArr[i].openSearch = false
          targetArr[i].searchConfig = {}
        }
      }
      // if (find && find.openSearch) {
      //   targetArr[i].openSearch = find.openSearch
      //   targetArr[i].searchConfig = find.searchConfig
      // } else {
      //   targetArr[i].openSearch = false
      //   targetArr[i].searchConfig = {}
      // }
    }
  }
  //删除数据绑定
  if (target['dataSourceBind'] && JSON.stringify(target['dataSourceBind']) === '{}') {
    delete target['dataSourceBind']
  }
  //递归处理数据
  for (let key in target) {
    if (key === 'data') {
      !target[key].formData && (target[key].formData = {})
      !target[key].requestData && (target[key].requestData = {})
      continue
    }
    if (key === 'rules') {
      continue
    }
    if (Array.isArray(target[key])) {
      forEachOwn(target[key], (itemDetail) => {
        extend(itemDetail, source)
      })
    } else if (toString.call(target[key]) === '[object Object]') {
      if (!sKeys.length) continue
      ExtendJson(target[key], findSource[key])
    } else {
      //未找到源对象不执行
      if (!sKeys.length || ctrl[0].ruleOut.indexOf(key) !== -1) continue
      //未找到属性删除
      if (!findSource[key]) {
        console.log(key)
        delete target[key]
        continue
      }
      //target[key] = findSource[key]
    }
  }
  return target
  //代码结束
}

//数据拆分
export function reArrayData(source, result) {
  isArray(source) &&
    source.forEach((item) => {
      if (!item.type) {
        reArrayData(item.list, result)
      } else {
        result.push(item)
      }
    })
  return result
}

function setChild(list, parentId) {
  for (let i = 0; i < list.length; i++) {
    list[i].parentId = parentId
    list[i].id = list[i]._id || parentId + list[i].field
    list[i].label = list[i].name || list[i].title
    list[i]._id = list[i].id
    if (list[i].children) {
      setChild(list[i].children, list[i].id)
    }
  }
}
//转换成树形结构
function getTreeData(sorceData = [], parentId, getType = []) {
  //处理列和表格右键函数
  function setcolumns(node, parentId) {
    const obj = {
      parentId: parentId,
      id: 'uiTable' + node.type + componentId(6),
      label: node.name,
      isParent: true,
      children: [],
    }
    obj._id = obj.id
    const columns = node.value
    for (let i = 0; i < columns.length; i++) {
      // if (!columns[i].field && node.type === 'exTableColumns') {
      //   continue
      // }
      //多级表头的
      if (columns[i]._type == 'seq') {
        continue
      }
      //处理树形的属性
      columns[i].parentId = obj._id
      columns[i].id = columns[i]._id || parentId + columns[i].field
      columns[i].label = columns[i].name || columns[i].title
      columns[i]._id = columns[i].id
      // columns[i].children = []
      console.log('children===', columns[i].children)
      if (columns[i].children) {
        setChild(columns[i].children, columns[i].id)
      } else {
        columns[i].children = []
      }
      //添加至child
      obj.children.push(columns[i])
    }
    return obj
  }

  let itemArr = []
  for (let i = 0; i < sorceData.length; i++) {
    let node = sorceData[i]
    if (node._parentId === parentId) {
      //普通组件
      let newNode = {}
      //父组件ID
      newNode.parentId = node._parentId
      //节点ID
      newNode.id = node._id
      //节点名称
      newNode.label = node.name
      //组件类型
      newNode.type = node.type
      //选中属性
      // newNode.isChecked = node.isChecked
      //是否是父级
      newNode.isParent = node.isParent
      //冗余一个_id属性方便后续判断
      newNode._id = node._id
      //树形子集
      newNode.children = getTreeData(sorceData, node._id, getType)
      //没有子集的父组件直接排除
      if (!newNode.children.length && node.isParent && !getType.includes(node.type)) continue
      //单独处理表格逻辑
      if (node.type === 'uiTable') {
        //处理列
        console.log(node.columns)
        node.columns.value.length && newNode.children.push(setcolumns(node.columns, node._id))
        //处理右键
        node.menuConfig.value.length && newNode.children.push(setcolumns(node.menuConfig, node._id))
        // obj.operateMenuConfig = list.extension.operateMenuConfig
        node.operateMenuConfig.value.length && newNode.children.push(setcolumns(node.operateMenuConfig, node._id))
      }
      itemArr.push(newNode)
    }
  }
  return itemArr
}

//extend events
function extendEvents(target, source = []) {
  const ctrl = [{ type: 'event', ruleOut: ['_id'] }]
  //获取目标对象
  const findSource =
    source.find((item) => {
      return item[ctrl[0].type] === target[ctrl[0].type]
    }) || {}
  const tkeys = Object.keys(target)
  const sKeys = Object.keys(findSource)
  forEachOwn(sKeys, (key) => {
    tkeys.indexOf(key) === -1 && (target[key] = findSource[key])
  })
  for (let key in target) {
    if (Array.isArray(target[key])) {
      forEachOwn(target[key], (itemDetail) => {
        extendEvents(itemDetail, source)
      })
    } else if (toString.call(target[key]) === '[object Object]') {
      if (!sKeys.length) continue
      ExtendJson(target[key], findSource[key])
    } else {
      //未找到源对象不执行
      if (!sKeys.length || ctrl[0].ruleOut.indexOf(key) !== -1) continue
      //未找到属性删除
      if (!findSource[key]) {
        delete target[key]
        continue
      }
      //target[key] = findSource[key]
    }
  }
}

//外部调用
export function extendData(target, source = []) {
  //深拷贝 原则不影响引用对象数据
  let _source = deepClone(target)
  _source = reArrayData(source, [])
  const _target = deepClone(target)
  //合并数据
  extend(_target, _source)
  //合并事件
  const actionArr = []
  action.forEach((item) => {
    actionArr.push(...item.list)
  })
  extendEvents(_target, actionArr)
  //处理数据
  return _target
}

//权限合并
//target 目标对象,source 源对象
export function extendPower(target, source = []) {
  // const matchField = ['_id']
  //const _args = Array.prototype.slice.call(arguments)
  //内部函数执行站
  function runExentd(target, source = []) {
    // if (_target.type == 'uiSplitpanes') {
    //   _target.list.forEach((row) => {
    //     row._id = `splitpanes_${componentId(6)}`
    //   })
    // }
    for (let key in target) {
      if (Array.isArray(target[key])) {
        target[key].forEach((detailItem) => {
          runExentd(detailItem, source)
        })
      } else if (toString.call(target[key]) === '[object Object]') {
        runExentd(target[key], source)
      } else {
        //找到匹配字段
        // if (matchField.indexOf(key) !== -1) {
        //   const _findObj = source.find((sour) => {
        //     return target[key] === (sour[matchField[0]] || sour)
        //   })
        //   if (_findObj) {
        //     target.isChecked = _findObj.isChecked === undefined ? true : _findObj.isChecked
        //   } else {
        //     target.isChecked = false
        //   }
        // }
      }
    }
    return target
  }
  //深拷贝 原则不影响引用对象数据
  const _target = deepClone(target),
    _source = deepClone(source) || []
  const result = runExentd(_target, _source)
  //返回执行结果
  return result
}
/*
提取目标组件
target提取的目标对象
result返回结果固定传个空数组
type数组结构需要提取的组件类型

调用方式
let result = getComponents(res, ["uiButton", "exTableMenuConfig"]);

*/
export function getComponents(target, type = []) {
  //获取结果
  function getReuslt(target, result = [], getType = []) {
    //添加数据
    function saveReuslt(list, parentType, parentId, result, isParent) {
      //处理为空或者为数字的情况
      if (!list._id || Number(list._id)) {
        list._id = parentType + parentId + componentId(6)
      }
      if (parentId != '-1000' && Number(parentId)) {
        parentId = parentType + parentId + componentId(6)
      }
      //判断是否是父级
      if (isParent === undefined) {
        isParent = list.list && list.list.length ? true : false
      }
      // if (list.type == 'collapseList') {
      //   console.log(getType.includes(list.type))
      // }
      //普通组件
      const obj = {
        _parentId: parentId,
        _id: list._id,
        name: list.name,
        type: list.type || null,
        isParent: isParent,
        isGetType: getType.includes(list.type),
        // isChecked: list.isChecked === undefined ? false : list.isChecked,
      }
      //表格组件
      if (obj.type === 'uiTable') {
        console.log(obj)
        obj.columns = list.extension.tableColumns
        obj.menuConfig = list.extension.menuConfig
        obj.operateMenuConfig = list.extension.operateMenuConfig
      }
      //添加至结果
      result.push(obj)
    }
    //递归循环list
    function forList(list = [], parentId, result) {
      for (let i = 0; i < list.length; i++) {
        //存储属性
        saveReuslt(list[i], 'PageListId', parentId, result)
        //有list继续循环
        if (list[i].list) {
          forList(list[i].list, list[i]._id, result)
        }
        if (list[i].boxBtnList) {
          forList(list[i].boxBtnList, list[i]._id, result)
        }
      }
    }

    //循环pageModules
    function forPageModules(list = [], parentId, result) {
      for (let i = 0; i < list.length; i++) {
        //存储属性
        saveReuslt(list[i], 'PageModulesId', parentId, result)
        //有list继续循环
        if (list[i].list) {
          forList(list[i].list, list[i]._id, result)
        }
        if (list[i].boxBtnList) {
          forList(list[i].boxBtnList, list[i]._id, result)
        }
      }
    }

    //顶层parentList计算
    function forParentList(list = [], parentId, result) {
      for (let i = 0; i < list.length; i++) {
        //处理为空或者为数字的情况
        if (!list[i]._id || Number(list[i]._id)) {
          list[i]._id = 'ParentId' + parentId + componentId(6)
        }
        //设置父级标识
        let parentFlag = false
        //存在page直接处理page
        if (list[i].pageModules) {
          forPageModules(list[i].pageModules, list[i]._id, result)
          parentFlag = true
        }
        //存在list递归自身
        if (list[i].list) {
          forParentList(list[i].list, list[i]._id, result)
          parentFlag = true
        }
        if (list[i].boxBtnList) {
          forList(list[i].boxBtnList, list[i]._id, result)
        }
        saveReuslt(list[i], 'ParentId', parentId, result, parentFlag)
      }
    }

    //开始处理数据
    const _target = target
    const _parentId = _target._id
    //最顶层处理
    saveReuslt(_target, '', '-1000', result, true)
    //处理顶层list
    forParentList(_target.list, _parentId, result)
    //处理顶层pageModules
    forPageModules(_target.pageModules, _parentId, result)
    //开始处理结果
    return result
  }

  //深拷贝对象
  const _target = deepClone(target)
  //默认taype
  !type.length && (type = ['uiButton'])
  //调用处理结果
  const resultArr = getReuslt(_target, [], type)
  //筛选结果
  return getTreeData(
    resultArr.filter((item) => {
      return item.isParent || item.isGetType
    }),
    '-1000',
    type
  )
}

//删除权限
export function deleteItems(target, roleJson) {
  console.log('deleteItems============')
  //顶层parentList计算
  function forParentList(list = []) {
    for (let i = 0; i < list.length; i++) {
      if (list[i].type && String(list[i].type).indexOf('uiSelectLayerNew') > -1) {
        continue
      }
      if (
        !roleJson.find((el) => el == list[i]._id) &&
        (['uiButton', 'uiUpload', 'uiDownload', 'uiTabs', 'TableMenu', 'uiTolead', 'tabsList', 'TableOperateMenu', 'uiDropdown'].includes(
          list[i].type
        ) ||
          list[i]._type === 'field' ||
          (list[i]._id && (list[i]._id + '').indexOf('tab_') > -1))
      ) {
        list.splice(i--, 1)
        continue
      }
      //存在page直接处理page
      if (list[i].pageModules) {
        forParentList(list[i].pageModules)
      }
      //存在list递归自身
      if (list[i].list) {
        forParentList(list[i].list)
      }
      //处理表头
      if (list[i].extension && list[i].extension.tableColumns) {
        forParentList(list[i].extension.tableColumns.value)
      }
      //处理表格操作
      if (list[i].extension && list[i].extension.operateMenuConfig) {
        forParentList(list[i].extension.operateMenuConfig.value)
      }
      //处理表格右键
      if (list[i].extension && list[i].extension.menuConfig) {
        forParentList(list[i].extension.menuConfig.value)
      }
    }
  }

  //调用执行
  forParentList(target.list)
  forParentList(target.pageModules)
  //返回数据
  return target
}

/*删除指定的对象属性 target
deleteEl参数以对象形式传入
例如
{
  requestData: '',
  formData: '',
}
*/
export function deleteElements(target, deleteEl = {}) {
  function clearValue(target, deleteEl) {
    //获取目标对象key
    const tkeys = Object.keys(target)
    //给属性赋值
    for (let key in deleteEl) {
      //判断是否存在key
      if (tkeys.includes(key)) {
        if (toString.call(deleteEl[key]) === '[object Object]' && JSON.stringify(deleteEl[key]) !== '{}') {
          clearValue(target[key], deleteEl[key])
        } else {
          target[key] = deleteEl[key]
        }
      }
    }
  }
  clearValue(target, deleteEl)
  //递归其他属性
  for (let key in target) {
    if (Array.isArray(target[key])) {
      forEachOwn(target[key], (itemDetail) => {
        deleteElements(itemDetail, deleteEl)
      })
    } else if (toString.call(target[key]) === '[object Object]') {
      deleteElements(target[key], deleteEl)
    }
  }
}

/*改变ID*/
export function changeFormItemID(list = []) {
  //定义组件类型
  var componentsArr = [
    'uiInput',
    'uiNumberInput',
    'uiButton',
    'uiSwitch',
    'uiCheckbox',
    'uiDate',
    'uiRadio',
    'uiSelect',
    'uiDropdown',
    'uiUpload',
    'uiDownload',
    'uiSelectLayerNew',
    'uiTolead',
    'uiIcon',
    'uiCascader',
    'uiTransfer',
  ]
  //判断目标组件函数
  function isTarget(type) {
    type = (type || '') + ''
    return type.indexOf('uiSelectLayerNew') > -1 || type.indexOf('uiSelectDown') > -1
  }
  //记录已修改的ID
  let _idArr = []
  //执行修改ID操作
  function changeItemID(list = [], __id) {
    for (let i = 0; i < list.length; i++) {
      //判断是否是目标组件
      if (list[i]._id && (componentsArr.includes(list[i].type) || isTarget(list[i].type))) {
        list[i]._id = __id ? list[i]._id + __id + '_' + i : list[i]._id + '_' + i
        //记录当前ID
        _idArr.push(list[i]._id)
        //处理条件数据
        list[i].logicInstruction.forEach((itemInst) => {
          //循环处理条件
          itemInst.conditionList.forEach((item) => {
            //更改条件ID
            _idArr.forEach((idItem) => {
              if (idItem.indexOf(item.condition.module) !== -1) {
                item.condition.module = idItem
              }
            })
          })
        })
      } else {
        list[i]._id = __id ? list[i]._id + __id + '_' + i : list[i]._id + '_' + i
      }
      if (list[i].list) {
        _idArr = __id ? _idArr : []
        __id ? changeItemID(list[i].list, `_${__id}_${i}`) : changeItemID(list[i].list, `_${i}`)
      }
    }
  }
  //运行函数
  changeItemID(list)
  //返回数据
  return list
}
